/*******************************************************************************
* Copyright (c) 2012-2014 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package com.codenvy.cli.command.builtin;
import com.codenvy.cli.command.builtin.helper.BeforeAfterAction;
import com.codenvy.cli.command.builtin.model.DefaultUserBuilderStatus;
import com.codenvy.cli.command.builtin.model.DefaultUserProject;
import com.codenvy.cli.command.builtin.model.DefaultUserProjectReference;
import com.codenvy.cli.command.builtin.model.DefaultUserRunnerStatus;
import com.codenvy.cli.command.builtin.model.DefaultUserWorkspace;
import com.codenvy.cli.command.builtin.model.UserBuilderStatus;
import com.codenvy.cli.command.builtin.model.UserProject;
import com.codenvy.cli.command.builtin.model.UserProjectReference;
import com.codenvy.cli.command.builtin.model.UserRunnerStatus;
import com.codenvy.cli.command.builtin.model.UserWorkspace;
import com.codenvy.cli.command.builtin.util.ascii.AsciiArray;
import com.codenvy.cli.command.builtin.util.ascii.AsciiForm;
import com.codenvy.cli.command.builtin.util.ascii.DefaultAsciiArray;
import com.codenvy.cli.command.builtin.util.ascii.DefaultAsciiForm;
import com.codenvy.cli.command.builtin.util.ascii.FormatterMode;
import com.codenvy.cli.command.builtin.util.metadata.CodenvyMetadata;
import com.codenvy.cli.command.builtin.util.zip.ZipUtils;
import com.codenvy.cli.preferences.Preferences;
import com.codenvy.cli.security.PreferencesDataStore;
import com.codenvy.cli.security.RemoteCredentials;
import com.codenvy.cli.security.TokenRetrieverDatastore;
import com.codenvy.client.Codenvy;
import com.codenvy.client.CodenvyClient;
import com.codenvy.client.CodenvyErrorException;
import com.codenvy.client.CodenvyException;
import com.codenvy.client.Request;
import com.codenvy.client.WorkspaceClient;
import com.codenvy.client.auth.CodenvyAuthenticationException;
import com.codenvy.client.auth.Credentials;
import com.codenvy.client.auth.Token;
import com.codenvy.client.model.BuilderStatus;
import com.codenvy.client.model.Project;
import com.codenvy.client.model.ProjectReference;
import com.codenvy.client.model.RunnerStatus;
import com.codenvy.client.model.Workspace;
import com.codenvy.client.model.WorkspaceReference;
import com.codenvy.client.model.project.ImportResponse;
import com.codenvy.client.model.runner.RunOptionsBuilder;
import org.apache.felix.service.command.CommandSession;
import org.apache.karaf.shell.console.CommandSessionHolder;
import org.fusesource.jansi.Ansi;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static com.codenvy.cli.command.builtin.util.ascii.FormatterMode.MODERN;
import static java.lang.String.format;
import static org.apache.karaf.shell.console.SessionProperties.PRINT_STACK_TRACES;
import static org.fusesource.jansi.Ansi.Attribute.INTENSITY_BOLD;
import static org.fusesource.jansi.Ansi.Attribute.INTENSITY_BOLD_OFF;
import static org.fusesource.jansi.Ansi.Color.RED;
/**
* @author Florent Benoit
*/
public class MultiRemoteCodenvy {
/**
* JSON file extension.
*/
protected static final String JSON_FILE_EXTENSION = ".json";
public static enum Importer {
GIT, ZIP;
}
private CodenvyClient codenvyClient;
private CommandSession session;
private ConcurrentMap<String, Codenvy> readyRemotes;
private ConcurrentMap<String, Remote> availableRemotes;
private Preferences globalPreferences;
public MultiRemoteCodenvy(CodenvyClient codenvyClient, Preferences globalPreferences, CommandSession session) {
this.codenvyClient = codenvyClient;
this.globalPreferences = globalPreferences;
this.session = session;
this.readyRemotes = new ConcurrentHashMap<>();
this.availableRemotes = new ConcurrentHashMap<>();
init();
}
protected void init() {
readyRemotes.clear();
availableRemotes.clear();
// now read remotes and add a new datastore for each env
Map preferencesRemotes = globalPreferences.get("remotes", Map.class);
if (preferencesRemotes != null) {
Iterator<String> remoteIterator = preferencesRemotes.keySet().iterator();
Preferences remotesPreferences = globalPreferences.path("remotes");
while (remoteIterator.hasNext()) {
String remote = remoteIterator.next();
// create store
PreferencesDataStore preferencesDataStore = new PreferencesDataStore(remotesPreferences, remote, codenvyClient);
// read remote
Remote remoteData = remotesPreferences.get(remote, Remote.class);
RemoteCredentials remoteCredentials = remotesPreferences.get(remote, RemoteCredentials.class);
// If token is available, add it
if (!remoteCredentials.getToken().isEmpty()) {
// add remote env
// Manage credentials
Codenvy codenvy = codenvyClient.newCodenvyBuilder(remoteData.getUrl(), remoteCredentials.getUsername())
.withCredentialsProvider(preferencesDataStore)
.withCredentialsStoreFactory(preferencesDataStore)
.build();
readyRemotes.put(remote, codenvy);
}
availableRemotes.put(remote, remoteData);
}
}
}
protected List<UserProjectReference> getProjects(String remoteName, boolean onlyPublic) {
Codenvy codenvy = readyRemotes.get(remoteName);
if (codenvy == null) {
Ansi buffer = Ansi.ansi();
buffer.fg(RED);
buffer.a(String.format("The remote %s doesn't exists", remoteName));
buffer.reset();
System.out.println(buffer.toString());
return Collections.emptyList();
}
return getProjects(remoteName, codenvy, onlyPublic);
}
protected List<UserProjectReference> getProjects() {
return getProjects(false);
}
protected List<UserProjectReference> getProjects(boolean onlyPublic) {
List<UserProjectReference> projects = new ArrayList<>();
Set<Map.Entry<String, Codenvy>> entries = readyRemotes.entrySet();
Iterator<Map.Entry<String, Codenvy>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, Codenvy> entry = iterator.next();
try {
List<UserProjectReference> foundProjects = getProjects(entry.getKey(), entry.getValue(), onlyPublic);
if (!foundProjects.isEmpty()) {
projects.addAll(foundProjects);
}
} catch (CodenvyAuthenticationException e) {
if (isStackTraceEnabled()) {
throw e;
}
System.err.println("Authentication token has expired on remote '" + entry.getKey() + "'. Please login again or logout on this remote to refresh the token.");
}
}
return projects;
}
/**
* Find the workspace with the specified name
*
* @param name
* the workspace name
* @param remote
* the remote name
* @param codenvy
* the codenvy object used to retrieve the data
* @return the list of workspaces
*/
protected UserWorkspace getWorkspaceWithName(String name, String remote, Codenvy codenvy) {
WorkspaceClient workspaceClient = codenvy.workspace();
Request<WorkspaceReference> request = workspaceClient.withName(name);
WorkspaceReference workspaceReference = request.execute();
if (workspaceReference == null) {
return null;
}
return new DefaultUserWorkspace(remote, this, codenvy, workspaceReference);
}
/**
* Gets list of all workspaces for the current user
*
* @param remote
* the remote name
* @param codenvy
* the codenvy object used to retrieve the data
* @return the list of workspaces
*/
protected List<UserWorkspace> getWorkspaces(String remote, Codenvy codenvy) {
List<UserWorkspace> workspaces = new ArrayList<>();
// get all workspaces
WorkspaceClient workspaceClient = codenvy.workspace();
Request<List<Workspace>> request = workspaceClient.all();
List<Workspace> readWorkspaces = request.execute();
for (Workspace workspace : readWorkspaces) {
WorkspaceReference ref = workspace.workspaceReference();
workspaces.add(new DefaultUserWorkspace(remote, this, codenvy, ref));
}
return workspaces;
}
/**
* Gets list of all projects for the current user
*
* @param codenvy
* the codenvy object used to retrieve the data
* @return the list of projects
*/
protected List<UserProjectReference> getProjects(String remote, Codenvy codenvy, boolean onlyPublic) {
List<UserProjectReference> projects = new ArrayList<>();
// For each workspace, search the project and compute
WorkspaceClient workspaceClient = codenvy.workspace();
Request<List<Workspace>> request = workspaceClient.all();
List<Workspace> readWorkspaces;
try {
readWorkspaces = request.execute();
} catch (CodenvyAuthenticationException e) {
if (isStackTraceEnabled()) {
throw e;
}
System.err.println("Authentication token has expired on remote '" + remote + "'. Please login again or logout on this remote to refresh the token.");
return projects;
} catch (CodenvyErrorException | CodenvyException e) {
if (isStackTraceEnabled()) {
throw e;
}
System.err.println("Error while retrieving projects on remote '" + remote + "'");
return projects;
}
for (Workspace workspace : readWorkspaces) {
WorkspaceReference ref = workspace.workspaceReference();
DefaultUserWorkspace defaultUserWorkspace = new DefaultUserWorkspace(remote, this, codenvy, ref);
List<ProjectReference> readProjects = codenvy.project().getWorkspaceProjects(ref.id()).execute();
for (ProjectReference readProject : readProjects) {
// skip private projects
if (onlyPublic && "private".equals(readProject.visibility())) {
continue;
}
DefaultUserProjectReference project = new DefaultUserProjectReference(codenvy, readProject, defaultUserWorkspace);
projects.add(project);
}
}
return projects;
}
/**
* Allows to search a project
*/
protected UserProjectReference getProjectReference(String shortId) {
if (shortId == null || shortId.length() < 2) {
throw new IllegalArgumentException("The identifier should at least contain two digits");
}
// get all projects
List<UserProjectReference> projects = getProjects();
// no projects
if (projects.isEmpty()) {
return null;
}
// now search in the given projects
List<UserProjectReference> matchingProjects = new ArrayList<>();
for (UserProjectReference project : projects) {
// match
if (project.shortId().startsWith(shortId)) {
matchingProjects.add(project);
}
}
// No matching project
if (matchingProjects.isEmpty()) {
return null;
} else if (matchingProjects.size() == 1) {
// one matching project
return matchingProjects.get(0);
} else {
throw new IllegalArgumentException("Too many matching projects. Try with a longer identifier");
}
}
/**
* Allows to search a project
*/
protected UserProject getProject(String shortId) {
UserProjectReference projectReference = getProjectReference(shortId);
if (projectReference == null) {
return null;
}
Project project = projectReference.getCodenvy().project().getProject(projectReference.getWorkspace().id(), projectReference.getInnerReference()).execute();
if (project == null) {
return null;
}
return new DefaultUserProject(projectReference.getCodenvy(), projectReference, project, projectReference.getWorkspace());
}
public boolean hasAvailableRemotes() {
return !availableRemotes.isEmpty();
}
public boolean hasReadyRemotes() {
return !readyRemotes.isEmpty();
}
public Collection<String> getRemoteNames() {
return availableRemotes.keySet();
}
public Map<String, Remote> getAvailableRemotes() {
return availableRemotes;
}
public Map<String, Codenvy> getReadyRemotes() {
return readyRemotes;
}
public String listRemotes() {
Ansi buffer = Ansi.ansi();
buffer.a(INTENSITY_BOLD).a("REMOTES\n").a(INTENSITY_BOLD_OFF);
buffer.reset();
Map<String, Remote> envs = getAvailableRemotes();
AsciiForm asciiForm = buildAsciiForm();
Iterator<Map.Entry<String, Remote>> it = envs.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Remote> entry = it.next();
String isDefault = "";
if (entry.getValue().isDefaultRemote()) {
isDefault = "*";
}
asciiForm.withEntry(" ".concat(entry.getKey().concat(isDefault)), "[".concat(entry.getValue().getUrl().concat("]")));
}
buffer.a(asciiForm.toAscii());
return buffer.toString();
}
public boolean addRemote(String name, String url) {
// check env doesn't exists
if (getRemoteNames().contains(name)) {
System.out.println("The remote with name '" + name + "' already exists");
return false;
}
Preferences preferencesRemotes = globalPreferences.path("remotes");
// add the new remote
Remote remote = new Remote();
remote.setUrl(url);
preferencesRemotes.put(name, remote);
// refresh current links
refresh();
return true;
}
public Remote getRemote(String remoteName) {
// it exists, get it
Preferences preferencesRemotes = globalPreferences.path("remotes");
if (!getRemoteNames().contains(remoteName)) {
return null;
}
return preferencesRemotes.get(remoteName, Remote.class);
}
public Remote getDefaultRemote() {
Map preferencesRemotes = globalPreferences.get("remotes", Map.class);
if (preferencesRemotes != null) {
Iterator<String> remoteIterator = preferencesRemotes.keySet().iterator();
Preferences remotesPreferences = globalPreferences.path("remotes");
while (remoteIterator.hasNext()) {
String remote = remoteIterator.next();
Remote tmpEnv = remotesPreferences.get(remote, Remote.class);
if (tmpEnv.isDefaultRemote()) {
return tmpEnv;
}
}
}
// No remote is an error case
throw new IllegalStateException("No default remote found. Needs to use --remote to specify a remote");
}
public String getDefaultRemoteName() {
Map preferencesRemotes = globalPreferences.get("remotes", Map.class);
if (preferencesRemotes != null) {
Iterator<String> remoteIterator = preferencesRemotes.keySet().iterator();
Preferences remotesPreferences = globalPreferences.path("remotes");
while (remoteIterator.hasNext()) {
String remote = remoteIterator.next();
Remote tmpRemote = remotesPreferences.get(remote, Remote.class);
if (tmpRemote.isDefaultRemote()) {
return remote;
}
}
}
// No remote is an error case
throw new IllegalStateException("No default remote found. Needs to use --remote to specify a remote");
}
/**
* Login by using a token instead of a password
* @param remoteName the remote on which we want to log in
* @param username the username (email)
* @param token the provided token
* @return true if login is successful
*/
public boolean login(String remoteName, String username, Token token) {
// get URL of the remote
Remote remote;
if (remoteName == null) {
remote = getDefaultRemote();
remoteName = getDefaultRemoteName();
} else {
remote = getRemote(remoteName);
}
if (remote == null) {
System.out.println("Unable to find the given remote '" + remoteName + "'");
return false;
}
String url = remote.getUrl();
// check that this is valid
Credentials codenvyCredentials = codenvyClient.newCredentialsBuilder()
.withUsername(username)
.withToken(token)
.build();
TokenRetrieverDatastore tokenRetrieverDatastore = new TokenRetrieverDatastore();
tokenRetrieverDatastore.put(username, codenvyCredentials);
Codenvy codenvy = codenvyClient.newCodenvyBuilder(url, username)
.withCredentials(codenvyCredentials)
.withCredentialsStoreFactory(tokenRetrieverDatastore)
.build();
// try to connect to the remote side
try {
codenvy.user().current().execute();
} catch (CodenvyException e) {
if (isStackTraceEnabled()) {
throw e;
}
System.out.println("Unable to authenticate for the given credentials on URL '" + url + "'. Check the provided token.");
// invalid login so we don't add env
return false;
}
// get token
Token tokenRetrieval = tokenRetrieverDatastore.getToken();
if (tokenRetrieval == null) {
System.out.println("Unable to validate token on URL '" + url + "'");
// invalid login so we don't add env
return false;
}
// Save credentials
Preferences preferencesRemotes = globalPreferences.path("remotes");
RemoteCredentials remoteCredentials = new RemoteCredentials();
remoteCredentials.setToken(token.value());
remoteCredentials.setUsername(username);
// by merging
preferencesRemotes.merge(remoteName, remoteCredentials);
// refresh current links
refresh();
return true;
}
public boolean login(String remoteName, String username, String password) {
// get URL of the remote
Remote remote;
if (remoteName == null) {
remote = getDefaultRemote();
remoteName = getDefaultRemoteName();
} else {
remote = getRemote(remoteName);
}
if (remote == null) {
System.out.println("Unable to find the given remote '" + remoteName + "'");
return false;
}
String url = remote.getUrl();
TokenRetrieverDatastore tokenRetrieverDatastore = new TokenRetrieverDatastore();
// check that this is valid
Credentials codenvyCredentials = codenvyClient.newCredentialsBuilder()
.withUsername(username)
.withPassword(password)
.build();
Codenvy codenvy = codenvyClient.newCodenvyBuilder(url, username)
.withCredentials(codenvyCredentials)
.withCredentialsStoreFactory(tokenRetrieverDatastore)
.build();
// try to connect to the remote side
try {
codenvy.user().current().execute();
} catch (CodenvyException e) {
if (isStackTraceEnabled()) {
throw e;
}
System.out.println("Unable to authenticate for the given credentials on URL '" + url + "'. Check the username and password.");
// invalid login so we don't add env
return false;
}
// get token
Token token = tokenRetrieverDatastore.getToken();
if (token == null) {
System.out.println("Unable to get token for the given credentials on URL '" + url + "'");
// invalid login so we don't add env
return false;
}
// Save credentials
Preferences preferencesRemotes = globalPreferences.path("remotes");
RemoteCredentials remoteCredentials = new RemoteCredentials();
remoteCredentials.setToken(token.value());
remoteCredentials.setUsername(username);
// by merging
preferencesRemotes.merge(remoteName, remoteCredentials);
// refresh current links
refresh();
return true;
}
/**
* Logout to the given remote cloud
* @param remoteName the remote name
* @return true if logout successfully
*/
public boolean logout(String remoteName) {
// get URL of the remote
Remote remote;
if (remoteName == null) {
remote = getDefaultRemote();
remoteName = getDefaultRemoteName();
} else {
remote = getRemote(remoteName);
}
if (remote == null) {
System.out.println("Unable to find the given remote '" + remoteName + "'");
return false;
}
// Get current credentials
Preferences preferencesRemotes = globalPreferences.path("remotes");
RemoteCredentials remoteCredentials = preferencesRemotes.get(remoteName, RemoteCredentials.class);
// disable token
remoteCredentials.setToken("");
// merge it
preferencesRemotes.merge(remoteName, remoteCredentials);
// refresh current links
refresh();
return true;
}
protected void refresh() {
init();
}
protected boolean removeRemote(String name) {
// check env does exists
if (!getRemoteNames().contains(name)) {
System.out.println("The remote with name '" + name + "' does not exists");
return false;
}
// it exists, remove it
Preferences preferencesRemotes = globalPreferences.path("remotes");
Remote remote = getRemote(name);
if (remote.isDefaultRemote()) {
System.out.println("The default remote cannot be removed.");
return false;
}
// delete
preferencesRemotes.delete(name);
// refresh current links
refresh();
// OK
return true;
}
protected boolean setDefaultRemote(String name) {
// check env does exists
if (!getRemoteNames().contains(name)) {
System.out.println("The remote with name '" + name + "' does not exists");
return false;
}
// Iterate on each remote, remove default except for the expected one
Map preferencesRemotes = globalPreferences.get("remotes", Map.class);
if (preferencesRemotes != null) {
// Iterate
Iterator<String> remoteIterator = preferencesRemotes.keySet().iterator();
Preferences remotesPreferences = globalPreferences.path("remotes");
while (remoteIterator.hasNext()) {
String remote = remoteIterator.next();
Remote tmpEnv = remotesPreferences.get(remote, Remote.class);
tmpEnv.setDefaultRemote(name.equals(remote));
remotesPreferences.merge(remote, tmpEnv);
}
}
// refresh current links
refresh();
// OK
return true;
}
public List<UserBuilderStatus> findBuilders(String builderID) {
// first collect all processes
List<UserProjectReference> projects = getProjects();
List<UserBuilderStatus> matchingStatuses = new ArrayList<>();
// then for each project, gets the builds IDs
for (UserProjectReference userProjectReference : projects) {
final List<BuilderStatus> builderStatuses = userProjectReference.getCodenvy().builder().builds(userProjectReference.getInnerReference()).execute();
for (BuilderStatus builderStatus : builderStatuses) {
UserBuilderStatus tmpStatus = new DefaultUserBuilderStatus(builderStatus, userProjectReference);
if (tmpStatus.shortId().startsWith(builderID)) {
matchingStatuses.add(tmpStatus);
}
}
}
return matchingStatuses;
}
public List<UserRunnerStatus> findRunners(String runnerID) {
List<UserProjectReference> projects = getProjects();
List<UserRunnerStatus> matchingStatuses = new ArrayList<>();
// then for each project, gets the process IDs
for (UserProjectReference userProjectReference : projects) {
final List<RunnerStatus> runnerStatuses =
userProjectReference.getCodenvy().runner().processes(userProjectReference.getInnerReference()).execute();
for (RunnerStatus runnerStatus : runnerStatuses) {
UserRunnerStatus tmpStatus = new DefaultUserRunnerStatus(runnerStatus, userProjectReference);
if (tmpStatus.shortId().startsWith(runnerID)) {
matchingStatuses.add(tmpStatus);
}
}
}
return matchingStatuses;
}
/**
* Gets project permissions
* @param userProjectReference
* @return
*/
public List<String> getProjectPermissions(UserProjectReference userProjectReference) {
Project project = userProjectReference.getCodenvy().project().getProject(userProjectReference.getWorkspace().id(), userProjectReference.getInnerReference()).execute();
if (project == null) {
return Collections.emptyList();
}
return project.permissions();
}
public List<UserRunnerStatus> getRunners(UserProjectReference userProjectReference) {
List<UserRunnerStatus> statuses = new ArrayList<>();
final List<RunnerStatus> runnerStatuses = userProjectReference.getCodenvy().runner().processes(userProjectReference.getInnerReference()).execute();
for (RunnerStatus runnerStatus : runnerStatuses) {
UserRunnerStatus tmpStatus = new DefaultUserRunnerStatus(runnerStatus, userProjectReference);
statuses.add(tmpStatus);
}
return statuses;
}
public List<UserBuilderStatus> getBuilders(UserProjectReference userProjectReference) {
List<UserBuilderStatus> statuses = new ArrayList<>();
final List<BuilderStatus> builderStatuses = userProjectReference.getCodenvy().builder().builds(userProjectReference.getInnerReference()).execute();
for (BuilderStatus builderStatus : builderStatuses) {
UserBuilderStatus tmpStatus = new DefaultUserBuilderStatus(builderStatus, userProjectReference);
statuses.add(tmpStatus);
}
return statuses;
}
protected static <T> T checkOnlyOne(List<T> list, String id, String textNoIdentifier, String textTooManyIDs) {
if (list.isEmpty()) {
errorNoIdentifier(id, textNoIdentifier);
return null;
} else if (list.size() > 1) {
errorTooManyIdentifiers(id, textTooManyIDs);
return null;
}
return list.get(0);
}
/**
* Display error if there are too many identifiers that have been found
* @param text a description of the identifier
*/
protected static void errorTooManyIdentifiers(String id, String text) {
Ansi buffer = Ansi.ansi();
buffer.fg(RED);
buffer.a("Too many ").a(text).a(" have been found with identifier '").a(id).a("'. Please add extra data to the identifier");
buffer.reset();
System.out.println(buffer.toString());
}
/**
* Display error if no identifier has been found
* @param text a description of the identifier
*/
protected static void errorNoIdentifier(String id, String text) {
Ansi buffer = Ansi.ansi();
buffer.fg(RED);
buffer.a("No ").a(text).a(" found with identifier '").a(id).a("'.");
buffer.reset();
System.out.println(buffer.toString());
}
public UserWorkspace getUserWorkspace(String remote, String workspaceName) {
// Remote ?
if (remote == null) {
remote = getDefaultRemoteName();
}
// try to connect to the remote
if (getRemote(remote) == null) {
System.out.println(format("The remote named %s doesn't exists", remote));
return null;
}
// check if remote is ready
Codenvy remoteCodenvy = getCodenvy(remote);
if (remoteCodenvy == null) {
System.out.println(format("The remote named %s is not yet available. Need to login first", remote));
return null;
}
UserWorkspace userWorkspace;
List<UserWorkspace> workspaces = getWorkspaces(remote, remoteCodenvy);
if (workspaceName == null) {
if (workspaces.size() > 1) {
System.out.println(format("Too many workspaces in the remote %s. Please specify the name of the workspace", remote));
return null;
} else if (workspaces.isEmpty()) {
System.out.println("No workspace found in the remote %s. Please specify another remote or create a workspace first");
return null;
}
userWorkspace = workspaces.get(0);
} else {
// needs to find the workspace
userWorkspace = getWorkspaceWithName(workspaceName, remote, remoteCodenvy);
if (userWorkspace == null) {
System.out.println(format("The workspace with name %s has not been found in the remote %s", workspaceName, remote));
return null;
}
}
return userWorkspace;
}
/**
*
* @param workspace
* @param name
* @param param
* @param importerType
* @return
*/
protected UserProjectReference importProject(UserWorkspace workspace, String name, String param, String importerType, Path configurationPath) {
//
String projectName = name;
// needs to analyze param
// 1]
// param is available on the current filesystem
File file = new File(param);
InputStream streamToSend;
boolean isDirectory = false;
if (file.exists()) {
if (projectName == null) {
projectName = file.getName();
}
// this is on the filesystem
if (file.isFile()) {
// 2a] json file ?
if (file.getName().endsWith(JSON_FILE_EXTENSION)) {
// remove .json extension
projectName = projectName.substring(0, projectName.length() - JSON_FILE_EXTENSION.length());
BeforeAfterAction beforeAfterAction = new BeforeAfterAction("Creating project from JSON file...", "Project created.");
Request<ImportResponse> importResponseRequest = workspace.getCodenvy().project().importProject(workspace.id(), projectName, file.toPath());
ImportResponse importResponse = beforeAfterAction.execute(importResponseRequest);
Project project = importResponse.project();
// Update it
beforeAfterAction = new BeforeAfterAction("Updating project configuration...", "Project configuration updated.");
Request<Project> updateRequest = workspace.getCodenvy().project().updateProject(project, file.toPath());
beforeAfterAction.execute(updateRequest);
return new DefaultUserProjectReference(workspace.getCodenvy(), project, workspace);
}
// 2] zip file ?
if (!file.getName().endsWith(".zip")) {
Ansi buffer = Ansi.ansi();
buffer.fg(RED);
buffer.a("The given file '").a(file.getName()).a("' should be a zip file.");
buffer.reset();
System.out.println(buffer.toString());
return null;
}
streamToSend = ZipUtils.getZipProjectStream(file);
} else {
// 3] directory, need to zip the content of this directory
isDirectory = true;
streamToSend = ZipUtils.getZipProjectStream(file);
}
// needs to create project
ProjectReference projectToCreate =
codenvyClient.newProjectBuilder().withName(projectName).withWorkspaceId(workspace.id()).withWorkspaceName(workspace.name()).withType(
"blank").build();
BeforeAfterAction beforeAfterAction = new BeforeAfterAction("Creating project from '" + file.getName() + "' ...", "Project created.");
Request<Project> createRequest = workspace.getCodenvy().project().create(projectToCreate);
try {
beforeAfterAction.execute(createRequest);
} catch (CodenvyErrorException | CodenvyException e) {
if (isStackTraceEnabled()) {
throw e;
}
System.out.println("Unable to create the project:" + e.getMessage());
return null;
}
// Project has been created, send the data
beforeAfterAction = new BeforeAfterAction("Uploading data from '" + file.getName() + "' ...", "Data uploaded.");
Request<Void> importArchiveRequest = workspace.getCodenvy().project().importArchive(workspace.id(), projectToCreate, streamToSend);
beforeAfterAction.execute(importArchiveRequest);
if (configurationPath != null) {
// Update it
beforeAfterAction = new BeforeAfterAction("Updating project configuration...", "Project configuration updated.");
Request<Project> updateRequest = workspace.getCodenvy().project().updateProject(projectToCreate, configurationPath);
beforeAfterAction.execute(updateRequest);
}
UserProjectReference userProjectReference = new DefaultUserProjectReference(workspace.getCodenvy(), projectToCreate, workspace);
// if directory, add Codenvy metadata in order to sync the project
if (isDirectory) {
storeMetadata(userProjectReference, file);
}
return userProjectReference;
} else {
// 4]
// not a file. is it a URL
URI uri;
try {
uri = new URI(param);
} catch (URISyntaxException e) {
Ansi buffer = Ansi.ansi();
buffer.fg(RED);
buffer.a("The given value '").a(param).a("' is neither a local path nor a valid URI.");
buffer.reset();
System.out.println(buffer.toString());
return null;
}
Importer importer = null;
if (importerType != null) {
importer = Importer.valueOf(importerType.toUpperCase(Locale.ENGLISH));
} else {
// try to autodetect type
if ("git".equals(uri.getScheme())) {
importer = Importer.GIT;
} else if (uri.toString().contains("github.com")) {
importer = Importer.GIT;
}
if (uri.toString().endsWith(".zip")) {
importer = Importer.ZIP;
}
}
// is it a git
if (importer == null) {
Ansi buffer = Ansi.ansi();
buffer.fg(RED);
buffer.a("Importer not given and auto-detect of the import type was not possible. Please provide the importer.");
buffer.reset();
System.out.println(buffer.toString());
return null;
}
// find name if not defined
if (projectName == null) {
projectName = uri.getPath().replace(".", "_").replace("/", "_");
}
// Create factory content
String factoryContent = "{\n" +
" \"v\" : \"2.0\",\n" +
" \"source\" : { \"project\" : { \"location\" : \"$LOCATION$\",\n" +
" \"type\" : \"$IMPORTER$\"\n" +
" }\n" +
" }\n" +
"}\n";
factoryContent = factoryContent.replace("$LOCATION$", param).replace("$IMPORTER$", importer.name().toLowerCase(Locale.ENGLISH));
// Dump the content
Path factoryPath;
try {
// create
factoryPath = Files.createTempFile(new File(System.getProperty("java.io.tmpdir")).toPath(), "factory", JSON_FILE_EXTENSION);
// dump
Files.write(factoryPath, factoryContent.getBytes(Charset.defaultCharset()));
} catch (IOException e) {
Ansi buffer = Ansi.ansi();
buffer.fg(RED);
buffer.a("Unable to generate factory content." + e.getMessage());
buffer.reset();
System.out.println(buffer.toString());
if (isStackTraceEnabled()) {
throw new IllegalArgumentException("Unable to generate factory content", e);
}
return null;
}
BeforeAfterAction beforeAfterAction = new BeforeAfterAction("Creating project from remote URI '" + uri.toString() + "' ...", "Project created.");
Request<ImportResponse> importResponseRequest = workspace.getCodenvy().project().importProject(workspace.id(), projectName, factoryPath);
ImportResponse importResponse = beforeAfterAction.execute(importResponseRequest);
Project project = importResponse.project();
if (configurationPath != null) {
// Update it
beforeAfterAction = new BeforeAfterAction("Updating project configuration...", "Project updated.");
Request<Project> updatedRequest = workspace.getCodenvy().project().updateProject(project, configurationPath);
beforeAfterAction.execute(updatedRequest);
}
return new DefaultUserProjectReference(workspace.getCodenvy(), project, workspace);
}
}
/**
* Creates a project with the given name
* @param name the name of the project to create
* @param workspaceName the name of the workspace
* @param remoteName the name of the remote
* @param configurationPath the configuration Factory JSON file
* @return the reference to the created project
*/
protected UserProjectReference createProject(String name, String workspaceName, String remoteName, Path configurationPath) {
// Remote ?
if (remoteName == null) {
remoteName = getDefaultRemoteName();
}
// try to connect to the remote
if (getRemote(remoteName) == null) {
System.out.println(format("The remote named %s doesn't exists", remoteName));
return null;
}
// check if remote is ready
Codenvy remoteCodenvy = readyRemotes.get(remoteName);
if (remoteCodenvy == null) {
System.out.println(format("The remote named %s is not yet available. Need to login first", remoteName));
return null;
}
UserWorkspace userWorkspace;
if (workspaceName == null) {
List<UserWorkspace> workspaces = getWorkspaces(remoteName, remoteCodenvy);
if (workspaces.size() > 1) {
System.out.println(format("Too many workspaces in the remote %s. Please specify the name of the workspace", remoteName));
return null;
} else if (workspaces.isEmpty()) {
System.out.println("No workspace found in the remote %s. Please specify another remote or create a workspace first");
return null;
}
userWorkspace = workspaces.get(0);
} else {
// needs to find the workspace
userWorkspace = getWorkspaceWithName(workspaceName, remoteName, remoteCodenvy);
if (userWorkspace == null) {
System.out.println(format("The workspace with name %s has not been found in the remote %s", workspaceName, remoteName));
return null;
}
}
// Let's create the project
// OK, now we have everything, we can create the project
ProjectReference projectToCreate =
codenvyClient.newProjectBuilder().withName(name).withWorkspaceId(userWorkspace.id()).withWorkspaceName(
workspaceName).withType("blank").build();
System.out.print("Creating project...");
try {
remoteCodenvy.project().create(projectToCreate).execute();
} catch (CodenvyErrorException e) {
if (isStackTraceEnabled()) {
throw e;
}
System.out.println("Unable to create the project:" + e.getMessage());
return null;
}
System.out.println("done !");
List<ProjectReference> projects = remoteCodenvy.project().getWorkspaceProjects(userWorkspace.id()).execute();
ProjectReference newProject = null;
for (ProjectReference project : projects) {
if (name.equals(project.name())) {
newProject = project;
break;
}
}
if (newProject == null) {
return null;
}
UserProjectReference builtUserProjectReference = new DefaultUserProjectReference(remoteCodenvy, newProject, userWorkspace);
// Update it
System.out.print("Now updating project configuration...");
remoteCodenvy.project().updateProject(builtUserProjectReference.getInnerReference(), configurationPath);
System.out.println("done !");
return builtUserProjectReference;
}
protected RunOptionsBuilder getRunOptionsBuilder() {
return codenvyClient.newRunOptionsBuilder();
}
protected boolean isStackTraceEnabled() {
// gets the current session
CommandSession commandSession = CommandSessionHolder.getSession();
if (commandSession != null) {
Boolean val = (Boolean)commandSession.get(PRINT_STACK_TRACES);
if (val != null && val.booleanValue()) {
return true;
}
}
return false;
}
/**
* @return the current formatter mode used at runtime
*/
protected FormatterMode getFormatterMode() {
FormatterMode formatterMode = (FormatterMode) session.get(FormatterMode.class.getName());
if (formatterMode == null) {
formatterMode = MODERN;
}
return formatterMode;
}
/**
* Build a new Ascii array instance with the selected formatter mode
* @return a new instance of the ascii array
*/
protected AsciiArray buildAsciiArray() {
return new DefaultAsciiArray().withFormatter(getFormatterMode());
}
/**
* Build a new Ascii array instance with the selected formatter mode
* @return a new instance of the ascii array
*/
protected AsciiForm buildAsciiForm() {
return new DefaultAsciiForm().withFormatter(getFormatterMode());
}
protected Codenvy getCodenvy(String remoteName) {
return readyRemotes.get(remoteName);
}
protected boolean storeMetadata(UserProjectReference project, File dest) {
try {
CodenvyMetadata codenvyMetadata = new CodenvyMetadata(project, dest);
codenvyMetadata.write();
} catch (Exception e) {
Ansi buffer = Ansi.ansi();
buffer.fg(RED);
buffer.a("Unable to write metadata in pulled project " + project.name());
buffer.reset();
System.out.println(buffer.toString());
return false;
}
return true;
}
}